<template>
  <el-sub-menu :index="props.index">
    <template #title>3dTitle</template>
    <el-menu-item index="3-1" @click="addIon3DTiles">Google逼真的3D瓦片</el-menu-item>
    <!-- <el-menu-item index="3-2" @click="addCustomize3DTiles">自定义</el-menu-item> -->
    <el-sub-menu index="3-2">
      <template #title>自定义模型</template>
      <el-menu-item index="3-2-1" @click="createDYT">大雁塔</el-menu-item>
      <el-menu-item index="3-2-2" @click="createWhite">白模数据</el-menu-item>
      <el-menu-item index="3-2-3" @click="createBIM">BIM建模</el-menu-item>
      <el-menu-item index="3-2-4" @click="createPipeline">地下管线</el-menu-item>
      <el-menu-item index="3-2-5" @click="addCustomize3DTiles">自定义</el-menu-item>
    </el-sub-menu>

    <el-menu-item index="3-3" v-if="!hasBuildings" @click="addBuildings">创建城市模型</el-menu-item>
    <el-sub-menu index="3-4" v-if="hasBuildings">
      <template #title>城市模型</template>
      <el-menu-item index="3-4-1" @click="flyToBuildings(tokyoTower)">东京</el-menu-item>
      <el-menu-item index="3-4-2" @click="flyToBuildings(kyotoNijoCastle)">京都</el-menu-item>
    </el-sub-menu>
  </el-sub-menu>
</template>

<script setup>
import * as Cesium from 'cesium'
import { useCesiumStore } from '@/stores/cesiumStore'
import { useTilesetStore } from '@/stores/tilesetStore'
import { ref } from 'vue'

// 定义props
const props = defineProps({
  index: {
    type: String,
    required: true,
  },
})
// 使用 Cesium Store
const cesiumStore = useCesiumStore()
// 使用 Tileset Store
const tilesetStore = useTilesetStore()
//cesiumStore.viewerCesium.scene.primitives.add 是向 Cesium 场景添加图元的方法，它允许将各种类型的 3D 对象添加到场景中进行渲染
//Google 逼真的 3D 瓦片
const addIon3DTiles = async () => {
  const tileset = cesiumStore.viewerCesium.scene.primitives.add(
    await Cesium.Cesium3DTileset.fromIonAssetId(
      // 用于实例化
      2275207,
      {
        enableDebugWireframe: true, //仅用于debug。要在 WebGL1 中工作，debugWireframe 必须开启。这不能在 tileset 加载后设置。
        debugFreezeFrame: true, //【冻结帧】选修的仅用于调试。确定是否只应使用最后一帧的图块进行渲染。-----
        debugColorizeTiles: true, //【着色】选修的仅用于调试。为真时，为每个图块分配随机颜色。
        debugWireframe: true, //【线框】选修的仅用于调试。为真时，将每个图块的内容渲染为线框。
        debugShowBoundingVolume: true, //【边界体积】选修的仅用于调试。当为真时，渲染每个图块的边界体积。
        debugShowContentBoundingVolume: true, //【内容卷】选修的仅用于调试。为真时，为每个图块的内容渲染边界体积。
        debugShowViewerRequestVolume: true, //【请求量】选修的仅用于调试。如果为真，则呈现每个图块的查看器请求体积。
        debugShowGeometricError: true, //【几何误差】选修的仅用于调试。为真时，绘制标签以指示每个图块的几何误差。
        debugShowRenderingStatistics: true, //【渲染统计】选修的仅用于调试。当为真时，绘制标签以指示每个图块的命令、点、三角形和特征的数量。
        debugShowMemoryUsage: true, //【内存使用】选修的仅用于调试。当为真时，绘制标签以指示每个图块使用的纹理和几何内存（以兆字节为单位）。
        debugShowUrl: true, //【网址】选修的仅用于调试。为真时，绘制标签以指示每个图块的 url。
      },
    ),
  )
  // cesiumStore.viewerCesium.flyTo(tileset)
}

// 加载自定义的3D Tiles资产
const addCustomize3DTiles = async () => {
  // 创建3D Tiles图层
  const tileset = await Cesium.Cesium3DTileset.fromUrl('http://localhost:5173/tiles/tileset.json', {
    maximumScreenSpaceError: 1, //最大的屏幕空间误差，越低越好   用于驱动细节层次优化的最大屏幕空间误差。
    // maximumNumberOfLoadedTiles: 1000, //最大加载瓦片个数，用于给定一定的限制，防止数据量过大，占用内存过高
    enableDebugWireframe: true, //仅用于debug。要在 WebGL1 中工作，debugWireframe 必须开启。这不能在 tileset 加载后设置。
    classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, //设置单体化模式
  })
  cesiumStore.viewerCesium.scene.primitives.add(tileset)
  cesiumStore.viewerCesium.flyTo(tileset)
}

//大雁塔
const createDYT = async () => {
  const tileset = await Cesium.Cesium3DTileset.fromUrl(
    'https://www.pipeser.com/cesiumlab/G7qC5vBk/tileset.json',
    {
      maximumScreenSpaceError: 1, //最大的屏幕空间误差，越低越好   用于驱动细节层次优化的最大屏幕空间误差。
      maximumNumberOfLoadedTiles: 1000, //最大加载瓦片个数，用于给定一定的限制，防止数据量过大，占用内存过高
    },
  )
  cesiumStore.viewerCesium.scene.primitives.add(tileset)
  cesiumStore.viewerCesium.flyTo(tileset)
}

const createWhite = async () => {
  tilesetStore.whiteModel = await Cesium.Cesium3DTileset.fromUrl(
    'https://www.pipeser.com/cesiumlab/7hfKb4S4/tileset.json',
    {
      maximumScreenSpaceError: 1, //最大的屏幕空间误差，越低越好   用于驱动细节层次优化的最大屏幕空间误差。
      maximumNumberOfLoadedTiles: 1000, //最大加载瓦片个数，用于给定一定的限制，防止数据量过大，占用内存过高
    },
  )
  console.log('tilesetStore.whiteModel创建成功')

  cesiumStore.viewerCesium.scene.primitives.add(tilesetStore.whiteModel)
  // 聚焦
  cesiumStore.viewerCesium.zoomTo(tilesetStore.whiteModel)
}
//BIM建模
const createBIM = async () => {
  const tileset = await Cesium.Cesium3DTileset.fromUrl(
    'https://www.pipeser.com/cesiumlab/jgYgbe3y/tileset.json',
    {
      maximumScreenSpaceError: 1, //最大的屏幕空间误差，越低越好   用于驱动细节层次优化的最大屏幕空间误差。
      maximumNumberOfLoadedTiles: 1000, //最大加载瓦片个数，用于给定一定的限制，防止数据量过大，占用内存过高
    },
  )
  cesiumStore.viewerCesium.scene.primitives.add(tileset)
  cesiumStore.viewerCesium.flyTo(tileset)
}
//地下管线
const createPipeline = async () => {
  const tileset = await Cesium.Cesium3DTileset.fromUrl(
    'https://www.pipeser.com/3dtiles/phipxrow1/tileset.json',
    {
      maximumScreenSpaceError: 1, //最大的屏幕空间误差，越低越好   用于驱动细节层次优化的最大屏幕空间误差。
      maximumNumberOfLoadedTiles: 1000, //最大加载瓦片个数，用于给定一定的限制，防止数据量过大，占用内存过高
    },
  )
  cesiumStore.viewerCesium.scene.primitives.add(tileset)
  cesiumStore.viewerCesium.flyTo(tileset)
}

//京都
const kyotoNijoCastle = {
  destination: new Cesium.Cartesian3(-3746418.0787567603, 3649244.7209161296, 3638967.47570257),
  orientation: {
    direction: new Cesium.Cartesian3(0.9417381486076588, -0.026110036454204615, 0.335331963065526),
    up: new Cesium.Cartesian3(-0.2518896785254185, 0.6059364940549604, 0.7545810460280222),
  },
}
//东京
const tokyoTower = {
  //摄像机在世界坐标中的最终位置
  destination: new Cesium.Cartesian3(-3959788.9678092706, 3353283.9088315447, 3697270.0292328526),
  //包含 direction 和 up 属性或 heading、pitch 和 roll 属性的对象。
  orientation: {
    direction: new Cesium.Cartesian3(0.1473261076519599, -0.9210400676146971, 0.3605276852787276),
    up: new Cesium.Cartesian3(-0.6082716434343354, 0.20305763470537083, 0.7673155835649066),
    // heading: Cesium.Math.toRadians(0), // 摇头，水平旋转，围绕Y轴，0为正北方向
    // pitch: Cesium.Math.toRadians(-90), // 点头，上下旋转，围绕X轴，-90为俯视地面
    // roll: Cesium.Math.toRadians(0), // 歪头，视口的翻滚角度，围绕Z轴，0为不翻转
  },
  duration: 5, // 飞行时间
}
const hasBuildings = ref(false)
//创建城市模型
const addBuildings = async () => {
  tilesetStore.osmBuildings = await Cesium.createOsmBuildingsAsync()
  // tilesetStore.osmBuildings.style = new Cesium.Cesium3DTileStyle({
  //   color: {
  //     conditions: [
  //       // 确保height存在且为数字
  //       ['Boolean(${height}) === true && Number(${height}) > 100', 'color("red", 0.8)'],
  //       ['Boolean(${height}) === true && Number(${height}) > 50', 'color("orange", 0.8)'],
  //       ['Boolean(${height}) === true && Number(${height}) > 20', 'color("blue", 0.8)'],
  //       ['true', 'color("white", 0.8)'],
  //     ],
  //   },
  //   show: true, // 所有建筑都显示
  // })

  cesiumStore.viewerCesium.scene.primitives.add(tilesetStore.osmBuildings)
  hasBuildings.value = true
}

//移动到城市模型
const flyToBuildings = (destination) => {
  cesiumStore.viewerCesium.scene.camera.flyTo(destination)
}
</script>

<style lang="scss" scoped></style>
